﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SharedComponents;
using System.Resources;
using System.Reflection;
using OurLeague.Object;
using Regex = System.Text.RegularExpressions.Regex;

namespace OurLeague
{
    public partial class frmBackEnd : Form
    {
        //accetta sequenze di caratteri esclusivamente alfabetici anche accentati. Spazi consentiti
        private const String REGEX_TEAM = @"^([a-zA-Z]+[òàùèìé]?\s?)+$";
        //accetta numeri da 1 a 99
        private const String REGEX_NUMERIC = @"^[1-9][0-9]?$";
        //accetta sequenze di caratteri non numerici e non speciali. Consente spazi e accentate finali
        private const String REGEX_FIRST_NAME = @"^([a-zA-z]+[òàùèìé]?\s?)+$";
        //accetta qualsiasi carattere non numerico e non speciale (eccetto zero o un apostrofo). Consente anche gli spazi e le accentate
        private const String REGEX_LAST_NAME = @"^([a-zA-Z]+[òàùèìé]?\s?)*([a-zA-Z]+[òàùèìé]?\'([a-zA-Z]+[òàùèìé]?\s?)+)?$";
        
        /// <summary>
        /// Una lista di liste di oggetti di tipo Control.
        /// Ogni posizione della lista rappresenta un insieme di oggetti grafici
        /// che figurano una "slide" (è assolutamente speculare ad una pagina del
        /// slidesContainer (oggetto TabControl) usato solo in modalità di Design).
        /// </summary>
        /// 
        #region Global

        List<List<Control>> _slidesControls;

        public frmBackEnd()
        {
            Application.UseWaitCursor = true;
            InitializeComponent();

            //Caricamento di _slideControls (potrebbe essere ottimizzato sfruttando metodi
            //per la manipolazione delle collezioni (ndr. che non ho avuto voglia di cercare).
            _slidesControls = new List<List<Control>>();
            foreach(TabPage tpage in tcBackEnd.TabPages)
            {
                _slidesControls.Add(new List<Control>());
                
                foreach(Control control in tpage.Controls)
                {
                    _slidesControls[_slidesControls.Count - 1].Add(control);
                }
            }

            setDefaultSettings();

            // Caricamento della prima slide
            showSlide(0);
            Application.UseWaitCursor = false;
        }

        private void setDefaultSettings()
        {
            // Global default settings
            Size = new Size(800, 615);
            Team.loadAll();
            Person.loadAll();
            Player.loadAll();

            // Teams default settings
            pnlDetailsTeam.Location = new Point(410, 62);
            //pnlEditTeam.Location = pnlDetailsTeam.Location;
            DataGridViewImageColumn editColumn = new DataGridViewImageColumn();
            editColumn.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
            editColumn.Image = OurLeague.Properties.Resources.pencil_icon;
            DataGridViewImageColumn delColumn = new DataGridViewImageColumn();
            delColumn.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
            delColumn.Image = OurLeague.Properties.Resources.delete_icon;
            dgTeams.Columns.Add(editColumn);
            dgTeams.Columns.Add(delColumn);
            dgTeams.AutoGenerateColumns = false;
            pnlEditTeam.Visible = false;
            pnlDetailsTeam.Visible = false;
            txtFilterTeamTm_TextChanged(null, null);

            // Players default settings
            pnlPlayerEditor.Location = new Point(432, 53);
            pnlPlayerDetails.Location = pnlPlayerEditor.Location;
            editColumn = new DataGridViewImageColumn();
            editColumn.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
            editColumn.Image = OurLeague.Properties.Resources.pencil_icon;
            delColumn = new DataGridViewImageColumn();
            delColumn.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
            delColumn.Image = OurLeague.Properties.Resources.delete_icon;
            dgPlayers.Columns.Add(editColumn);
            dgPlayers.Columns.Add(delColumn);
            dgPlayers.AutoGenerateColumns = false;
            cmbChooseTeamPl.Items.Clear();
            cmbTeamPlayer.Items.Clear();
            cmbChooseTeamPl.Items.Add("Non selezionata");

            foreach (Team team in Team.Teams)
            {
                cmbChooseTeamPl.Items.Add(team.Name);
                cmbTeamPlayer.Items.Add(team.Name);
            }

            cmbChooseTeamPl.SelectedIndex = 0;
            cmbTeamPlayer.SelectedIndex = 0;
            cmbChooseTeamPl_SelectedIndexChanged(null, null);

            // Dayweeks default settings
            Match.loadAll();
            DataGridViewImageColumn viewColumn = new DataGridViewImageColumn();
            viewColumn.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
            viewColumn.Image = OurLeague.Properties.Resources.zoom_icon;
            editColumn = new DataGridViewImageColumn();
            editColumn.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
            editColumn.Image = OurLeague.Properties.Resources.pencil_icon;
            delColumn = new DataGridViewImageColumn();
            delColumn.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
            delColumn.Image = OurLeague.Properties.Resources.delete_icon;
            dgDayweekDetails.Columns.Add(viewColumn);
            dgDayweekDetails.Columns.Add(delColumn);
            dgDayweekDetails.AutoGenerateColumns = false;
            viewColumn = new DataGridViewImageColumn();
            viewColumn.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
            viewColumn.Image = OurLeague.Properties.Resources.zoom_icon;
            delColumn = new DataGridViewImageColumn();
            delColumn.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
            delColumn.Image = OurLeague.Properties.Resources.delete_icon;
            dgDayweeks.Columns.Add(editColumn);
            dgDayweeks.Columns.Add(delColumn);
            dgDayweeks.AutoGenerateColumns = false;
            Dayweek.loadAll();
            cmbLocalTeam.DisplayMember = "Name";
            cmbLocalTeam.ValueMember = "Id";
            cmbGuestTeam.DisplayMember = "Name";
            cmbGuestTeam.ValueMember = "Id";
            refreshDayweeksGrid();

            // Lineup default settings
            dgLineUp.AutoGenerateColumns = false;
            delColumn = new DataGridViewImageColumn();
            delColumn.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
            delColumn.Image = OurLeague.Properties.Resources.delete_icon;
            dgEvents.Columns.Add(delColumn);
            dgEvents.AutoGenerateColumns = false;
        }

        public void showSlide(int slideIndex)
        {
            pnlBackEnd.Controls.Clear();
            pnlBackEnd.Controls.AddRange(_slidesControls[slideIndex].ToArray());
        }


        #endregion

        #region Players

        private void smiPlayers_Click(object sender, EventArgs e)
        {
            showSlide(1);
        }

        private void cmbChooseTeamPl_SelectedIndexChanged(object sender, EventArgs e)
        {
            dgPlayers.DataSource = getPlayersBindingList(cmbChooseTeamPl.Text, txtFilterTeamPl.Text);
            lblTotPlayer.Text = "Tot. " + dgPlayers.RowCount;
            lblPlayerNotSelected.Visible = (dgPlayers.RowCount == 0);
            pnlPlayerDetails.Visible = !lblPlayerNotSelected.Visible;
        }

        private List<Player> getPlayersBindingList(String teamName, String playerName)
        {
            List<Player> selectionOfPlayers;
            Team R;
            playerName = playerName.Trim().ToLower();
            Func<Player, bool> filterByName = P => P.Name.ToLower().StartsWith(playerName) || P.Surname.ToLower().StartsWith(playerName);
            Func<Player, bool> filterByTeam = P => P.TeamId == ((R = Team.Teams.Find(T => T.Name == cmbChooseTeamPl.Text)) != null ? R.Id : null);

            if (teamName != "Non selezionata" && playerName.Count() > 0)
                selectionOfPlayers = Player.Players.FindAll(P => filterByName(P) && filterByTeam(P));
            else if (playerName.Count() > 0)
                selectionOfPlayers = Player.Players.FindAll(P => filterByName(P));
            else if (teamName != "Non selezionata")
                selectionOfPlayers = Player.Players.FindAll(P => filterByTeam(P));
            else
                selectionOfPlayers = Player.Players;

            return selectionOfPlayers.ToList();
        }

        private void txtFilterTeamPl_TextChanged(object sender, EventArgs e)
        {
            cmbChooseTeamPl_SelectedIndexChanged(null, null);
        }

        private void dgPlayers_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if (dgPlayers.RowCount == 0 || e.RowIndex < 0)
                return;

            switch (e.ColumnIndex)
            {
                case 4:
                    {
                        btmEditPlayer_Click(null, null);

                        break;
                    }

                case 5:
                    {
                        btmRemove_Click(null, null);
                        break;
                    }
            }
        }

        private void dgPlayers_SelectionChanged(object sender, EventArgs e)
        {
            if (dgPlayers.SelectedRows.Count == 0 || pnlPlayerEditor.Visible)
                return;

            DataGridViewRow selectedRow = dgPlayers.SelectedRows[0];
            Player selectedPlayer = Player.load(selectedRow.Cells[0].Value.ToString());
            DateTime dateBorn = selectedPlayer.Birthday;

            lblFirstName.Text = selectedPlayer.Name;
            lblLastName.Text = selectedPlayer.Surname;
            lblBirthplace.Text = selectedPlayer.Birthplace;
            lblBirthday.Text = dateBorn.ToString("d");
            lblStatus.Text = selectedPlayer.Status.ToString();
            lblNationality.Text = selectedPlayer.Nationality;
            lblTeamPlayer.Text = selectedPlayer.TeamName;
            lblRole.Text = selectedPlayer.Role;
            lblNumber.Text = selectedPlayer.ShirtNumber.ToString();
            lblFoot.Text = selectedPlayer.Foot == 0 ? "Sinistro" : "Destro";
            lblHeight.Text = String.Format("{0:0.#}", selectedPlayer.Height);
            lblWeight.Text = String.Format("{0:0.#}", selectedPlayer.Weight);
            lblPlayerNotSelected.Visible = false;
        }

        private void btnAbort_Click(object sender, EventArgs e)
        {
            pnlPlayerEditor.Visible = false;
            pnlPlayerDetails.Visible = true;
            lblPlayerNotSelected.Visible = (dgPlayers.RowCount == 0);
            pnlPlayerDetails.Visible = !lblPlayerNotSelected.Visible;
            pnlPlayerBrowser.Enabled = true;
        }


        private void btnSavePlayer_Click(object sender, EventArgs e)
        {
            int shirtNumber = int.Parse(txtNumber.Text);

            //controllo dati
            if (!Regex.IsMatch(txtLastName.Text.Trim(), REGEX_LAST_NAME) || !Regex.IsMatch(txtFirstName.Text.Trim(), REGEX_FIRST_NAME) || shirtNumber == 0)
            {
                MessageBox.Show("Qualche campo obbligatorio presenta un formato non valido.", "Errore", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            Player selectedPlayer;
            Team team = Team.getTeamFromName(cmbTeamPlayer.Text);
            if (lblTitlePlayerEditor.Text == "Modifica giocatore")
            {
                DataGridViewRow selectedRow = dgPlayers.SelectedRows[0];
                selectedPlayer = Player.load(selectedRow.Cells[0].Value.ToString());
            }
            else
                selectedPlayer = new Player();

            if (Player.Players.Exists(p => p != selectedPlayer && p.ShirtNumber == shirtNumber && p.TeamId == team.Id))
            {
                MessageBox.Show("Qualche giocatore della squadra '" + team.Name + "' possiede già il numero di maglia specificato.", "Errore", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (MessageBox.Show("Sei sicuro di voler proseguire con l'operazione?", "Modifica giocatore", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                selectedPlayer.Name = txtFirstName.Text.Trim();
                selectedPlayer.Surname = txtLastName.Text.Trim();
                selectedPlayer.ShirtNumber = shirtNumber;
                selectedPlayer.Height = int.Parse(txtHeight.Text);
                selectedPlayer.Weight = int.Parse(txtWeight.Text);
                selectedPlayer.Status = int.Parse(txtStatus.Text);
                selectedPlayer.Birthplace = txtBirthplace.Text.Trim();
                selectedPlayer.Birthday = txtBirthday.Value;
                selectedPlayer.Foot = cmbFoot.SelectedIndex;
                selectedPlayer.Role = cmbRole.Text;
                selectedPlayer.Nationality = txtNationality.Text.Trim();
                selectedPlayer.TeamId = team.Id;
                selectedPlayer.save();

                txtFilterTeamPl.Text = "";
                cmbChooseTeamPl.SelectedIndex = 0;
                cmbChooseTeamPl_SelectedIndexChanged(null, null);
                btnAbort_Click(null, null);
            }
        }

        private void btnResetPlayer_Click(object sender, EventArgs e)
        {
            txtFirstName.Text = "";
            txtLastName.Text = "";
            txtBirthplace.Text = "";
            txtBirthday.Text = "";
            txtNationality.Text = "";
            cmbTeamPlayer.SelectedIndex = 0;
            cmbRole.SelectedIndex = 0;
            txtNumber.Text = "";
            cmbFoot.SelectedIndex = 0;
            txtHeight.Text = "0";
            txtWeight.Text = "0";
            txtNumber.Text = "0";
            txtBirthday.Value = DateTime.Parse("01-01-1975");
        }

        private void btnAddPlayer_Click(object sender, EventArgs e)
        {
            lblTitlePlayerEditor.Text = "Nuovo giocatore";
            pnlPlayerBrowser.Enabled = false;
            pnlPlayerDetails.Visible = false;
            btmRemove.Visible = false;
            pnlPlayerEditor.Visible = true;
            btnResetPlayer_Click(null, null);
        }

        private void btmEditPlayer_Click(object sender, EventArgs e)
        {
            lblTitlePlayerEditor.Text = "Modifica giocatore";

            DataGridViewRow selectedRow = dgPlayers.SelectedRows[0];
            Player selectedPlayer = Player.load(selectedRow.Cells[0].Value.ToString());
            DateTime dateBorn = selectedPlayer.Birthday;

            txtFirstName.Text = selectedPlayer.Name;
            txtLastName.Text = selectedPlayer.Surname;
            txtBirthplace.Text = selectedPlayer.Birthplace;
            txtBirthday.Value = dateBorn;
            txtNationality.Text = selectedPlayer.Nationality;
            cmbTeamPlayer.Text = selectedPlayer.TeamName;
            txtStatus.Text = selectedPlayer.Status.ToString();
            cmbRole.Text = selectedPlayer.Role;
            txtNumber.Text = selectedPlayer.ShirtNumber.ToString();
            cmbFoot.SelectedIndex = selectedPlayer.Foot;
            txtHeight.Text = String.Format("{0:0.#}", selectedPlayer.Height);
            txtWeight.Text = String.Format("{0:0.#}", selectedPlayer.Weight);

            btmRemove.Visible = true;
            pnlPlayerBrowser.Enabled = false;
            pnlPlayerDetails.Visible = false;
            pnlPlayerEditor.Visible = true;
        }

        private void btmRemove_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Sei sicuro di voler proseguire con l'operazione?", "Cancellazione giocatore", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                DataGridViewRow selectedRow = dgPlayers.SelectedRows[0];
                Player selectedPlayer = Player.load(selectedRow.Cells[0].Value.ToString());
                bool check = selectedPlayer.delete();
                
                if (!check)
                    MessageBox.Show("Cancellazione non permessa, il giocatore specificato è di dipendenza per altre informazioni.", "Errore cancellazione", MessageBoxButtons.OK, MessageBoxIcon.Error);
                cmbChooseTeamPl_SelectedIndexChanged(null, null);
                btnAbort_Click(null, null);
            }
        }

        private void btmRemovePlayer2_Click(object sender, EventArgs e)
        {
            btmRemove_Click(null, null);
        }

        private void txtStatus_KeyPress(object sender, KeyPressEventArgs e)
        {
            acceptOnlyNumber(e);
        }

        private void acceptOnlyNumber(KeyPressEventArgs e)
        {
            if (!Regex.IsMatch(e.KeyChar.ToString(), "^[\\d|\\b]+$"))
                e.Handled = true;
        }

        private void txtHeight_KeyPress(object sender, KeyPressEventArgs e)
        {
            acceptOnlyNumber(e);
        }

        private void txtWeight_KeyPress(object sender, KeyPressEventArgs e)
        {
            acceptOnlyNumber(e);
        }

        private void setToZero(object txtObject)
        {
            TextBox txt = ((TextBox)txtObject);
            if (txt.Text.Count() == 0)
                txt.Text = "0";
        }

        private void txtNumber_KeyPress(object sender, KeyPressEventArgs e)
        {
            acceptOnlyNumber(e);
        }

        private void txtStatus_Leave(object sender, EventArgs e)
        {
            setToZero(sender);
        }

        private void txtHeight_Leave(object sender, EventArgs e)
        {
            setToZero(sender);
        }

        private void txtWeight_Leave(object sender, EventArgs e)
        {
            setToZero(sender);
        }

        private void txtNumber_Leave(object sender, EventArgs e)
        {
            setToZero(sender);
        }

        #endregion

        #region Teams

        private void smiTeams_Click(object sender, EventArgs e)
        {
            showSlide(0);
        }

        private DataTable getTeamDataTable(String teamName)
        {
            List<Team> selectionOfTeam;
            Func<Team, bool> filterByTeam = T => T.Name.ToLower().StartsWith(teamName.Trim().ToLower());
            if (teamName.Count() > 0)
                selectionOfTeam = Team.Teams.FindAll(T => filterByTeam(T));
            else
                selectionOfTeam = Team.Teams;
            DataTable dt = new DataTable();
            dt.Columns.Add("teamId", typeof(String));
            dt.Columns.Add("name", typeof(String));
            
            DataRow myNewRow;

            foreach (Team team in selectionOfTeam)
            {
                myNewRow = dt.NewRow();
                myNewRow["teamID"] = team.Id;
                myNewRow["name"] = team.Name;
  
                dt.Rows.Add(myNewRow);
            }
            return dt;

        }
        private void txtFilterTeamTm_TextChanged(object sender, EventArgs e)
        {
            dgTeams.DataSource = getTeamDataTable(txtFilterTeamTm.Text);
            lblTotTeams.Text = "Tot. " + dgTeams.RowCount;
            lblTeamNotSelected.Visible = (dgTeams.RowCount == 0);
            pnlDetailsTeam.Visible = !lblTeamNotSelected.Visible;
        }

        private void dgTeams_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if (dgTeams.RowCount == 0 || e.RowIndex < 0) return;

            switch (e.ColumnIndex)
            {
                case 2:
                    {
                        //Edit
                        btnEditTeam_Click(null, null);

                        break;
                    }

                case 3:
                    {
                        //Cancel
                        btnCancelTeam_Click(null, null);
                        break;
                    }
            }
        }

        private void dgTeams_SelectionChanged(object sender, EventArgs e)
        {
            if (dgTeams.SelectedRows.Count == 0 || pnlEditTeam.Visible)
                return;
          
            DataGridViewRow selectedRow = dgTeams.SelectedRows[0];
            Team selectedTeam = Team.load(selectedRow.Cells[0].Value.ToString());
            imgTeamLogo.Image = Util.loadImageFromResources(selectedTeam.Name.ToLower());
            lblName.Text = selectedTeam.Name;
            lblCity.Text = selectedTeam.RegisteredOffice;
            lblStadium.Text = selectedTeam.Stadium;
            lblPresident.Text = selectedTeam.President; 
            Coach c = Coach.load(selectedTeam.CoachId);
            lblCoach.Text = c.Name + " " + c.Surname;
            lblNPlayers.Text = Player.Players.FindAll(P => P.TeamId == selectedTeam.Id).Count.ToString();
            availableCoaches(c);
        }

        private void btnEditTeam_Click(object sender, EventArgs e)
        {
            lblEditTeam.Text = "Modifica squadra";

            DataGridViewRow selectedRow = dgTeams.SelectedRows[0];
            Team selectedTeam = Team.load(selectedRow.Cells[0].Value.ToString());
            txtName.Text =  selectedTeam.Name;
            txtCity.Text =  selectedTeam.RegisteredOffice;
            txtStadium.Text = selectedTeam.Stadium;
            txtPresident.Text =  selectedTeam.President;
            availableCoaches(Coach.Coaches.Find(c => c.Id == selectedTeam.CoachId));

            pnlEditTeam.Visible = true;
            pnlDetailsTeam.Visible = false;
            pnlTeamBrowser.Enabled = false;
        }

        private void btnQuitTeam_Click(object sender, EventArgs e)
        {
            pnlEditTeam.Visible = false;
            lblTeamNotSelected.Visible = (dgTeams.RowCount == 0);
            pnlDetailsTeam.Visible = !lblTeamNotSelected.Visible;
            pnlTeamBrowser.Enabled = true;
        }

        private void btnCancelTeam_Click(object sender, EventArgs e)
        {
            if (Dayweek.Dayweeks.Count != 0)
            {
                MessageBox.Show("Non è possibile aggiungere od elimare squadre se il campionato è già in corso.", "Operazione non permessa", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            if (MessageBox.Show("Sei sicuro di voler cancellare?", "Cancella squadra", MessageBoxButtons.YesNo, MessageBoxIcon.Question)==DialogResult.Yes){
                DataGridViewRow selectedRow = dgTeams.SelectedRows[0];
                Team selectedTeam = Team.load(selectedRow.Cells[0].Value.ToString());
                
                bool check = selectedTeam.delete();
                if (!check)
                    MessageBox.Show("Cancellazione non permessa, la squadra specificata è di dipendenza per altre informazioni.", "Errore cancellazione", MessageBoxButtons.OK, MessageBoxIcon.Error);
                
                txtFilterTeamTm_TextChanged(null, null);
                btnQuitTeam_Click(null, null);
            }
        }

        private void btnCancelTeam2_Click(object sender, EventArgs e)
        {
            btnCancelTeam_Click(null, null);
        }

        private void btnResetTeam_Click(object sender, EventArgs e)
        {
            txtName.Text = "";
            txtCity.Text = "";
            txtPresident.Text = "";
            txtStadium.Text = "";
            if (btnCancelTeam.Visible)
            {
                DataGridViewRow selectedRow = dgTeams.SelectedRows[0];
                Team selectedTeam = Team.load(selectedRow.Cells[0].Value.ToString());

                cmbCoach.SelectedValue = selectedTeam.CoachId;
            }
            else
            {
                cmbCoach.SelectedIndex = 0;

            }

            //availableCoaches(Coach.load(selectedTeam.CoachID));
        }

        private void btnAddTeam_Click(object sender, EventArgs e)
        {
            if (Dayweek.Dayweeks.Count != 0 )
            {
                MessageBox.Show("Non è possibile aggiungere od elimare squadre se il campionato è già in corso.", "Operazione non permessa", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            availableCoaches(null);
            if (cmbCoach.SelectedItem == null)
            {
                MessageBox.Show("Non è possibile inserire una nuova squadra poichè non ci sono allenatori svincolati.", "Inserimento squadra", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }
            
            txtName.Text = "";
            txtCity.Text = "";
            txtPresident.Text = "";
            txtStadium.Text = "";
            
            lblEditTeam.Text = "Nuova squadra";
            pnlDetailsTeam.Visible = false;
            pnlEditTeam.Visible = true;
            btnCancelTeam.Visible = false;
            pnlTeamBrowser.Enabled = false;
        }

        private void btnSaveTeam_Click(object sender, EventArgs e)
        {
            //controllo dati
            if (!Regex.IsMatch(txtName.Text.Trim(), REGEX_LAST_NAME))
            {
                MessageBox.Show("Il nome della squadra ha un formato non valido.", "Errore", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (MessageBox.Show("Confermi l'operazione?", lblEditTeam.Text == "Modifica squadra" ? "Modifica" : "Inserimento", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {   
                Team selectedTeam;
                if (lblEditTeam.Text == "Modifica squadra")
                {
                    DataGridViewRow selectedRow = dgTeams.SelectedRows[0];
                    selectedTeam = Team.load(selectedRow.Cells[0].Value.ToString());
                }
                else
                    selectedTeam = new Team();

                //controllo dati
                if ((lblEditTeam.Text=="Modifica squadra" && Team.Teams.Exists(T=> T.Name.ToLower().Trim()==txtName.Text.ToLower().Trim() && T.Id!=selectedTeam.Id))||(lblEditTeam.Text=="Nuova squadra" && Team.Teams.Exists(T=> T.Name.ToLower().Trim()==txtName.Text.ToLower().Trim())))
                {   
                    MessageBox.Show(txtName.Text+" è già presente all'interno del sistema. Inserire un nome diverso", "Errore", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                selectedTeam.Name = txtName.Text.Trim();
                selectedTeam.RegisteredOffice = txtCity.Text.Trim();
                selectedTeam.President = txtPresident.Text.Trim();
                selectedTeam.Stadium = txtStadium.Text.Trim();
                selectedTeam.CoachId = cmbCoach.SelectedValue.ToString();

                selectedTeam.save();
                txtFilterTeamTm.Text = "";
                txtFilterTeamTm_TextChanged(null, null);
                btnQuitTeam_Click(null, null);
            }
        }

        /// <summary>
        /// Stampa una combobox con la lista degli allenatori disponibili più (eventualmente) quello attuale
        /// </summary>
        /// <param name="c">Allenatore attuale</param>
        private void availableCoaches(Coach c)
        {
            Coach.loadAll();
            DataTable dt = new DataTable();
            dt.Columns.Add("id", typeof(String));
            dt.Columns.Add("name", typeof(String));
            if (c != null)
                dt.Rows.Add(c.Id, c.Name + " " + c.Surname);
            foreach (Coach coach in Coach.Coaches)
                if (!Team.Teams.Exists(T => T.CoachId == coach.Id))
                    dt.Rows.Add(coach.Id, coach.Name + " " + coach.Surname);
            cmbCoach.DisplayMember = "name";
            cmbCoach.ValueMember = "id";
            cmbCoach.DataSource = dt;
            if (c!= null)
                cmbCoach.SelectedValue = c.Id;
        }
        #endregion

        #region LineUp

        private void btnBackUI_Click(object sender, EventArgs e)
        {
            smiDayweeks.Text = "Giornate";
            smiDayweeks_Click(null, null);
        }

        private void cmbChooseTeamLU_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cmbChooseTeamLU.SelectedValue == null) return;
            Match selectedMatch;
            DataGridViewRow selectedRow = dgDayweekDetails.SelectedRows[0];
            selectedMatch = Match.load(selectedRow.Cells[0].Value.ToString());
            dgLineUp.DataSource = getLineUp(cmbChooseTeamLU.SelectedValue.ToString(), selectedMatch);
            updateLineUpCount();
        }

        private DataTable getLineUp(String idTeam, Match m)
        {
            LineUp lu;
            if (m.LocalLineUp.TeamId==idTeam)
                lu=m.LocalLineUp;
            else
                lu=m.GuestLineUp;

            if ((lu.RegularPlayers.Count != LineUp.REGULAR) && (!Team.canPlay(idTeam)))
            {
                MessageBox.Show("Devi avere una rosa di minimo " + (LineUp.REGULAR + LineUp.RESERVE) + " giocatori disponibili (tra cui 2 portieri) per scendere in campo", "Errore", MessageBoxButtons.OK, MessageBoxIcon.Error);
                dgLineUp.Enabled = false;
                btnSaveLineUp.Enabled = false;
                return new DataTable();
            }
            dgLineUp.Enabled = true;

            DataTable dt = new DataTable();
            dt.Columns.Add("playerId", typeof(String));
            dt.Columns.Add("shirtNumber",typeof(int));
            dt.Columns.Add("name", typeof(String));
            dt.Columns.Add("surname", typeof(String));
            dt.Columns.Add("role", typeof(String));
            dt.Columns.Add("status", typeof(int));
            dt.Columns.Add("cards", typeof(int));
            dt.Columns.Add("isRegular", typeof(int));
            dt.Columns.Add("isReserve", typeof(int));

            manageLineUp(dt, lu.RegularPlayers, 1, 0);
            manageLineUp(dt, lu.ReservePlayers, 0, 1);
            
            //partita conclusa
            if (m.Played || Event.Events.Exists(E => E.MatchId == m.Id))
            {
                btnSaveLineUp.Enabled = false;
                dgLineUp.Columns[5].Visible = dgLineUp.Columns[6].Visible = false;
                dgLineUp.ReadOnly = true;
                lblNotAvailable.Visible = false;
            }
            else
            {
                Player.loadAll();
                manageLineUp(dt, lu.notLineUp(1), 0, 0);
                //partita già in corso
                /*if (Event.Events.Exists(E => E.MatchId == m.Id)){
                    btnSaveLineUp.Enabled = false;
                    dgLineUp.ReadOnly=true;
                }
                else
                {*/
                    btnSaveLineUp.Enabled = true;
                    dgLineUp.ReadOnly = false;
                    dgLineUp.Columns[5].Visible = dgLineUp.Columns[6].Visible = true;
                    int i = 1;
                    while (i < 7)
                    {
                        dgLineUp.Columns[i].ReadOnly = true;
                        i++;
                    }
                //}
                //stampo lista indisponili
                lblNotAvailable.Visible=true;
                lblNotAvailable.Text="Indisponibili: ";
                foreach (Player p in Player.Players.FindAll(P => P.TeamId == lu.TeamId && !P.isAvailable()))
                    lblNotAvailable.Text += p.Name + " " + p.Surname + " (" + ((p.Status==0) ? "squalificato" : "infortunato") + "), ";
                if (lblNotAvailable.Text == "Indisponibili: ")
                    lblNotAvailable.Text += "nessuno.";
                else
                lblNotAvailable.Text = lblNotAvailable.Text.Trim().Remove(lblNotAvailable.Text.Trim().Length-1)+".";
            }
            return dt;        

        }
        /// <summary>
        /// Popola il datagrid a seconda che si tratti di inserire titolari, riserve o rosa completa
        /// <param name="dt">DataTable da popolare</param>
        /// <param name="player">Lista di giocatori</param>
        /// <param name="regular">Insieme a reserve: 1-0 per titolare, 0-1 per riserve, 0-0 per rosa</param>
        /// <param name="reserve">Insieme a regular: 1-0 per titolare, 0-1 per riserve, 0-0 per rosa</param>
        /// </summary>
        private void manageLineUp(DataTable dt, List<Player> player, int regular, int reserve)
        {
            DataRow row;
            foreach (Player p in player)
            {
                row = dt.NewRow();

                row["playerId"] = p.Id;
                row["shirtNumber"] = p.ShirtNumber;
                row["name"] = p.Name;
                row["surname"] = p.Surname;
                row["role"] = p.Role;
                row["status"] = p.Status;
                row["cards"] = p.Cards;
                row["isRegular"] = regular;
                row["isReserve"] = reserve;
                dt.Rows.Add(row);
            }
        }
        
        private void tcLineUpEvents_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (tcLineUpEvents.SelectedTab == tpEvents)
            {
                pnlEvent2.Visible = false;
                Match selectedMatch;
                DataGridViewRow selectedRow = dgDayweekDetails.SelectedRows[0];
                selectedMatch = Match.load(selectedRow.Cells[0].Value.ToString());

                if (selectedMatch.LocalLineUp.RegularPlayers.Count != LineUp.REGULAR || selectedMatch.GuestLineUp.RegularPlayers.Count != LineUp.REGULAR)
                {
                    tcLineUpEvents.SelectedTab = tpLineUp;
                    MessageBox.Show("Per iniziare la partita le formazioni devono essere entrambe schierate.", "Errore", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                //popolo la combo con gli eventi
                String[] eventType = new String[] { "Gol", "Cartellini", "Sostituzioni", "Infortunio", "Rigore" };
                cmbChooseEvent.DataSource = eventType;
                refreshEventsGrid(selectedMatch.Id);
                if (selectedMatch.Played)
                {
                    pnlEvent.Enabled = false;
                    dgEvents.Columns[5].Visible = false;
                }
                else
                {
                    pnlEvent.Enabled = true;
                    dgEvents.Columns[5].Visible = true;
                }
                //buildCmbTeams();
                //buildCmbPlayers();
            }
            else
                cmbChooseTeamLU_SelectedIndexChanged(null, null);
            pnlEvent2.Visible = true;
        }

        private void buildCmbTeams()
        {
            //popolo combo squadre
            Match selectedMatch;
            DataGridViewRow selectedRow = dgDayweekDetails.SelectedRows[0];
            selectedMatch = Match.load(selectedRow.Cells[0].Value.ToString());
            Team[] lineUp = new Team[] { Team.load(selectedMatch.LocalLineUp.TeamId), Team.load(selectedMatch.GuestLineUp.TeamId) };
            cmbChooseTeamEv.DisplayMember = "Name";
            cmbChooseTeamEv.ValueMember = "Id";
            cmbChooseTeamEv.DataSource = lineUp;
        }

        private void buildCmbPlayers(int kind)
        {
            //popolo combo giocatori titolari o riserve
            Match selectedMatch;
            DataGridViewRow selectedRow = dgDayweekDetails.SelectedRows[0];
            selectedMatch = Match.load(selectedRow.Cells[0].Value.ToString());
            LineUp ln = selectedMatch.LocalLineUp.TeamId == cmbChooseTeamEv.SelectedValue.ToString() ?
            selectedMatch.LocalLineUp : selectedMatch.GuestLineUp;
            
            ComboBox cmb = (kind==0)? cmbChoosePlayerEv : cmbChoosePlayerIn;
            cmb.DataSource = (kind==0)? ln.regularNow(selectedMatch.Id) : ln.onTheBenchNow(selectedMatch.Id);
            cmb.ValueMember = "id";
            cmb.DisplayMember = "SurnameAndN";
        }

        private void remainSub()
        {
            Match selectedMatch;
            DataGridViewRow selectedRow = dgDayweekDetails.SelectedRows[0];
            selectedMatch = Match.load(selectedRow.Cells[0].Value.ToString());
            LineUp ln = selectedMatch.LocalLineUp.TeamId == cmbChooseTeamEv.SelectedValue.ToString() ?
            selectedMatch.LocalLineUp : selectedMatch.GuestLineUp;
            lblRemain.Text="Sostituzioni rimaste: "+ln.remainSubstitutions(selectedMatch.Id).ToString();
            if (ln.remainSubstitutions(selectedMatch.Id) == 0)
                cmbChoosePlayerIn.Enabled = false;
            else
                cmbChoosePlayerIn.Enabled = true;
        }

        private void setTxtMinute()
        {
            Match selectedMatch;
            DataGridViewRow selectedRow = dgDayweekDetails.SelectedRows[0];
            selectedMatch = Match.load(selectedRow.Cells[0].Value.ToString());
            int last = Event.lastEvent(selectedMatch.Id);
            if (last == 0)
            {
                txtMinute.Text = dudHalf.Text = "1";
                return;
            }
            if (last > 100)
            {
                last -= 100;
                dudHalf.Text = "2";
            }
            else
                dudHalf.Text = "1";
            txtMinute.Text = last.ToString();            
        }

        private void updateLineUpCount()
        {
            int i = 0;
            int reserve = 0;
            int regular = 0;
            while (i < dgLineUp.RowCount)
            {
                reserve += (int)dgLineUp.Rows[i].Cells[8].Value;
                regular += (int)dgLineUp.Rows[i].Cells[7].Value;
                i++;
            }
            lblNRegular.Text = regular.ToString();
            lblNReserves.Text = reserve.ToString();
            if (regular != LineUp.REGULAR)
                lblNRegular.ForeColor = Color.Red;
            else
                lblNRegular.ForeColor = Color.Green;
            if (reserve != LineUp.RESERVE)
                lblNReserves.ForeColor = Color.Red;
            else
                lblNReserves.ForeColor = Color.Green;
        }

        private void bntLineUpHel_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Le formazioni possono essere confermate solo dopo aver selezionato " + LineUp.REGULAR + " titolari e " + LineUp.RESERVE + " riserve.\nIn caso non si disponga di "+(LineUp.RESERVE+LineUp.REGULAR)+" giocatori disponibili procedere all'inserimento di un nuovo giocatore (simulando il caso reale di prestito dalla squadra giovanile).\nIl match potrà iniziare solo se entrambe le formazioni sono confermate.\nA partita iniziatà non sarà possibile modificare gli schieramenti.\nCliccare sul tab Eventi per la gestione della partita.", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information); 
        }

        private void matchStatus(Match m)
        {
            lblMatchStatus.Text = "";
            if (m.Played)
            {
                lblMatchStatus.Text = "Partita conclusa";
                return;
            }
            if (Event.Events.Exists(E => E.MatchId == m.Id))
            {
                lblMatchStatus.Text = "Partita in corso";
                return;
            }
            if (m.LocalLineUp.RegularPlayers.Count == LineUp.REGULAR)
            {
                if (m.GuestLineUp.RegularPlayers.Count == LineUp.REGULAR)
                    lblMatchStatus.Text = m.LocalLineUp.TeamName + " ha schierato la formazione. " + m.GuestLineUp.TeamName + " ha schierato la formazione. La partita può giocarsi.";
                else
                    lblMatchStatus.Text = m.LocalLineUp.TeamName + " ha schierato la formazione. " + m.GuestLineUp.TeamName + " non ha ancora schierato la formazione. La partita non può iniziare.";
            }
            else
            {
                if (m.GuestLineUp.RegularPlayers.Count == LineUp.REGULAR)
                    lblMatchStatus.Text = m.LocalLineUp.TeamName + " non ha ancora schierato la formazione. " + m.GuestLineUp.TeamName + " ha schierato la formazione. La partita non può iniziare.";
                else
                    lblMatchStatus.Text = "Le squadre non hanno ancora schierato le loro formazioni. La partita non può iniziare.";
            }
        }

        private void btnSaveLineUp_Click(object sender, EventArgs e)
        {
            List<Player> regular = new List<Player>();
            List<Player> reserve = new List<Player>();
            int i = 0;

            while (i < dgLineUp.Rows.Count)
            {
                if ((int)dgLineUp.Rows[i].Cells[7].Value == 1)
                    regular.Add(Player.Players.Find(P => P.Id == dgLineUp.Rows[i].Cells[0].Value.ToString()));
                if ((int)dgLineUp.Rows[i].Cells[8].Value == 1)
                    reserve.Add(Player.Players.Find(P => P.Id == dgLineUp.Rows[i].Cells[0].Value.ToString()));
                i++;
            }
            if (!LineUp.checkLineUp(regular, reserve))
            {
                MessageBox.Show("La formazione non rispetta i vincoli imposti.", "Errore", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            DataGridViewRow selectedRow = dgDayweekDetails.SelectedRows[0];
            Match selectedMatch = Match.load(selectedRow.Cells[0].Value.ToString());
            LineUp ln = selectedMatch.LocalLineUp.TeamId == cmbChooseTeamLU.SelectedValue.ToString() ? 
                              selectedMatch.LocalLineUp : selectedMatch.GuestLineUp;
            ln.RegularPlayers = regular;
            ln.ReservePlayers = reserve;
            ln.save();
            
            MessageBox.Show("Formazione salvata correttamente", "OK", MessageBoxButtons.OK, MessageBoxIcon.Information);
            matchStatus(selectedMatch);
        }

        private void cmbChooseEvent_SelectedIndexChanged(object sender, EventArgs e)
        {
            //DataGridViewRow selectedRow = dgDayweekDetails.SelectedRows[0];
            //Match selectedMatch = Match.load(selectedRow.Cells[0].Value.ToString());
            //selectedMatch = Match.load(selectedRow.Cells[0].Value.ToString());

            Point locationBtnOne = new Point(110, 310);
            Point locationBtnTwo = new Point(179, 310);
            Point locationBtn = new Point (145, 310);
            Point locationCkb = new Point(50, 263);

            buildCmbTeams();
            buildCmbPlayers(0);
            btnAddEvent.Enabled = true;

            switch (cmbChooseEvent.SelectedIndex)
            {
                //gol
                case 0:
                    {
                        lblPlayerEv2.Visible = lblIn.Visible = lblOut.Visible= cmbChoosePlayerIn.Visible = false;
                        ckbIsGoal.Visible = lblRemain.Visible = btnAddEventRed.Visible = false;
                        ckbIsDisallow.Visible=true;
                        ckbIsDisallow.Checked = false;
                        ckbIsDisallow.Location=locationCkb;
                        btnAddEvent.Image = OurLeague.Properties.Resources.ball;
                        btnAddEvent.Location = locationBtn;
                        lblInjury.Visible = dudInjury.Visible = false;
                        break;
                    }
                //cartellino
                case 1:
                    {
                        lblPlayerEv2.Visible = lblIn.Visible =lblOut.Visible= cmbChoosePlayerIn.Visible = false;
                        ckbIsGoal.Visible = lblRemain.Visible = ckbIsDisallow.Visible = false;
                        btnAddEventRed.Visible = true;
                        btnAddEventRed.Location = locationBtnTwo;
                        btnAddEvent.Location = locationBtnOne;
                        btnAddEvent.Image = OurLeague.Properties.Resources.yellow;
                        lblInjury.Visible = dudInjury.Visible = false;
                        cmbChoosePlayerEv_SelectedIndexChanged(null, null);
                        break;
                    }
                //sostituzione
                case 2:
                    {
                        lblRemain.Visible = lblPlayerEv2.Visible = lblOut.Visible= lblIn.Visible = cmbChoosePlayerIn.Visible = true;
                        ckbIsDisallow.Visible = ckbIsGoal.Visible = btnAddEventRed.Visible = false;
                        btnAddEvent.Location = locationBtn;
                        btnAddEvent.Image = OurLeague.Properties.Resources.inout;
                        buildCmbPlayers(1);
                        lblInjury.Visible = dudInjury.Visible = false;
                        remainSub();
                        break;
                    }
                //infortunio
                case 3:
                    {
                        lblPlayerEv2.Visible = lblIn.Visible = lblOut.Visible = cmbChoosePlayerIn.Visible = false;
                        ckbIsGoal.Visible = btnAddEventRed.Visible = ckbIsDisallow.Visible = lblRemain.Visible= false;
                        btnAddEvent.Location = locationBtn;
                        btnAddEvent.Image = OurLeague.Properties.Resources.injury;
                        lblInjury.Visible = dudInjury.Visible = true;
                        dudInjury.Text = "1";
                        break;
                    }
                //rigore
                case 4:
                    {
                        lblPlayerEv2.Visible = lblIn.Visible = lblOut.Visible = cmbChoosePlayerIn.Visible = false;
                        ckbIsDisallow.Visible = btnAddEventRed.Visible = lblRemain.Visible = false;
                        ckbIsGoal.Visible = true;
                        ckbIsGoal.Checked = false;
                        ckbIsGoal.Location = locationCkb;
                        btnAddEvent.Image = OurLeague.Properties.Resources.penalty;
                        btnAddEvent.Location = locationBtn;
                        lblInjury.Visible = dudInjury.Visible = false;
                        break;
                    }

            }

        }
        private void btnAddEvent_Click(object sender, EventArgs e)
        {
            DataGridViewRow selectedRow = dgDayweekDetails.SelectedRows[0];
            Match selectedMatch = Match.load(selectedRow.Cells[0].Value.ToString());

            LineUp ln = selectedMatch.LocalLineUp.TeamId == cmbChooseTeamEv.SelectedValue.ToString() ? 
                              selectedMatch.LocalLineUp : selectedMatch.GuestLineUp;

            int last = Event.lastEvent(selectedMatch.Id);
            if (last != 0)
            {
                int min = (dudHalf.Text.Trim() == "2") ? 100 + int.Parse(txtMinute.Text.Trim()) : int.Parse(txtMinute.Text.Trim());
                if (min < last)
                {
                    MessageBox.Show("Non puoi inserire un evento precendente ad un altro", "Errore", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }

            Event ev = new Event();

            switch (cmbChooseEvent.SelectedIndex)
            {
                //gol
                case 0:
                    {
                        ev.Type = (ckbIsDisallow.Checked) ? 7 : 1;
                        break;
                    }
                //cartellini
                case 1:
                    {
                        ev.Type = 2;
                        break;
                    }
                //sostituzione
                case 2:
                    {
                        //controllo se posso far entrare giocatori
                        if (cmbChoosePlayerIn.Enabled == true)
                        {
                            Event ev2 = new Event();
                            ev2.MatchId = selectedMatch.Id;
                            ev2.Type = 4;
                            ev2.Minute = int.Parse(txtMinute.Text.Trim());
                            ev2.Half = int.Parse(dudHalf.Text);
                            ev2.Player = Player.load(cmbChoosePlayerIn.SelectedValue.ToString());
                            ev2.LineUpPlayerId = ev2.getLineUpPlayerId(ln.Id);
                            ev2.save();
                        }
                        ev.Type = 5;
                        remainSub();
                        break;
                    }
                //infortunio
                case 3:
                    {
                        ev.Type = 6;
                        //aggiorno lo stato del giocatore
                        Player.load(cmbChoosePlayerEv.SelectedValue.ToString()).getInjury(int.Parse(dudInjury.Text.Trim()));
                        break;
                    }
                //rigore
                case 4:
                    {
                        ev.Type = 8;
                        if (ckbIsGoal.Checked)
                        {
                            Event ev2 = new Event();
                            ev2.MatchId = selectedMatch.Id;
                            ev2.Type = 1;
                            ev2.Minute = int.Parse(txtMinute.Text.Trim());
                            ev2.Half = int.Parse(dudHalf.Text);
                            ev2.Player = Player.load(cmbChoosePlayerEv.SelectedValue.ToString());
                            ev2.LineUpPlayerId = ev2.getLineUpPlayerId(ln.Id);
                            ev2.save();
                        }
                        break;
                    }
            }
            ev.MatchId = selectedMatch.Id;
            ev.Minute = int.Parse(txtMinute.Text.Trim());
            ev.Half = int.Parse(dudHalf.Text);
            ev.Player = Player.load(cmbChoosePlayerEv.SelectedValue.ToString());
            ev.LineUpPlayerId = ev.getLineUpPlayerId(ln.Id);
            ev.save();
            buildCmbPlayers(0);
            buildCmbPlayers(1);
            refreshEventsGrid(selectedMatch.Id);

            //MessageBox.Show("Ultimo evento: " + res[1] + "° " + res[0] + "T");
        }

        private void refreshEventsGrid(String matchId)
        {
            setTxtMinute();
            dgEvents.DataSource = Event.Events.FindAll(E => E.MatchId == matchId).OrderByDescending(EV => EV.Minute).OrderByDescending(EV => EV.Half).ToList();
            lblResult.Text = Match.load(matchId).Result;
            //dgEvents.DataSource = new BindingList<Event>(Event.Events.FindAll(E => E.MatchId == matchId).OrderByDescending(EV => EV.Id).ToList());
        }

        private void cmbChooseTeamEv_SelectedIndexChanged(object sender, EventArgs e)
        {
            buildCmbPlayers(0);
            buildCmbPlayers(1);
            remainSub();
            btnAddEvent.Enabled = true;
            cmbChoosePlayerEv_SelectedIndexChanged(null, null);
        }

        private void btnAddEventRed_Click(object sender, EventArgs e)
        {
            DataGridViewRow selectedRow = dgDayweekDetails.SelectedRows[0];
            Match selectedMatch = Match.load(selectedRow.Cells[0].Value.ToString());

            LineUp ln = selectedMatch.LocalLineUp.TeamId == cmbChooseTeamEv.SelectedValue.ToString() ?
                              selectedMatch.LocalLineUp : selectedMatch.GuestLineUp;

            int last = Event.lastEvent(selectedMatch.Id);
            if (last != 0)
            {
                int min = (dudHalf.Text.Trim() == "2") ? 100 + int.Parse(txtMinute.Text.Trim()) : int.Parse(txtMinute.Text.Trim());
                if (min < last)
                {
                    MessageBox.Show("Non puoi inserire un evento precendente ad un altro", "Errore", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }
            Event ev = new Event();
            ev.Type = 3;
            ev.MatchId = selectedMatch.Id;
            ev.Minute = int.Parse(txtMinute.Text.Trim());
            ev.Half = int.Parse(dudHalf.Text);
            ev.Player = Player.load(cmbChoosePlayerEv.SelectedValue.ToString());
            ev.LineUpPlayerId = ev.getLineUpPlayerId(ln.Id);
            ev.save();
            buildCmbPlayers(0);
            buildCmbPlayers(1);
            refreshEventsGrid(selectedMatch.Id);
        }

        private void cmbChoosePlayerEv_SelectedIndexChanged(object sender, EventArgs e)
        {
            btnAddEvent.Enabled = true;
            switch (cmbChooseEvent.SelectedIndex)
            {
                case 1:
                    {
                        DataGridViewRow selectedRow = dgDayweekDetails.SelectedRows[0];
                        Match selectedMatch = Match.load(selectedRow.Cells[0].Value.ToString());
                        selectedMatch = Match.load(selectedRow.Cells[0].Value.ToString());
                        if (Player.load(cmbChoosePlayerEv.SelectedValue.ToString()).hasYellow(selectedMatch.Id))
                            btnAddEvent.Enabled = false;
                        else
                            btnAddEvent.Enabled = true;
                        break;
                    }
            }
        }

        private void dgEvents_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if (dgEvents.RowCount == 0 || e.RowIndex < 0)
                return;

            switch (e.ColumnIndex)
            {
                case 5:
                    {
                        if (MessageBox.Show("Sei sicuro di voler proseguire con l'operazione?", "Cancellazione evento", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                        {
                            var row = dgEvents.Rows[e.RowIndex];
                            Event ev = Event.load(row.Cells[0].Value.ToString());
                            switch (ev.Type)
                            {
                                case 4:
                                case 5:
                                    {
                                        List<Event> substitutionEvents = Event.Events.FindAll(eev => eev.MatchId == ev.MatchId && eev.Half == ev.Half && eev.Minute == ev.Minute && eev.Type == (ev.Type == 4 ? 5 : 4));

                                        if (substitutionEvents.Count > 0)
                                        {
                                            Event choosedSubstitutionevent = substitutionEvents[0];
                                            if (substitutionEvents.Count > 1)
                                            {
                                                SubstitutionEventForm sef = new SubstitutionEventForm(substitutionEvents);
                                                sef.lblMessage.Text = "Con chi era stato sostituito " + ev.Player.Name + " " + ev.Player.Surname + "?";
                                                sef.ShowDialog();
                                                choosedSubstitutionevent = (Event)sef.cmbSubstitutions.SelectedItem;
                                                if (!sef.Response)
                                                    return;
                                            }

                                            Event inEvent = ev.Type == 4 ? ev : choosedSubstitutionevent;

                                            List<Event> ghostEvents = Event.Events.FindAll(eev => (eev.Half == inEvent.Half && eev.Minute >= inEvent.Minute || eev.Half > inEvent.Half) && eev.Player == inEvent.Player && eev.MatchId == inEvent.MatchId);
                                            foreach (Event evv in ghostEvents)
                                                evv.delete();
                                            choosedSubstitutionevent.delete();
                                        }

                                        ev.delete();
                                        break;
                                    }
                                case 6:
                                    {
                                        ev.Player.Status = 0;
                                        ev.Player.save();
                                        break;
                                    }
                            }
                            ev.delete();
                            refreshEventsGrid(ev.MatchId);
                        }
                        break;
                    }

            }
        }

        private void btnEndMatch_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Sei sicuro di voler terminare la partita?", "Fine partita", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                DataGridViewRow selectedRow = dgDayweekDetails.SelectedRows[0];
                Match selectedMatch = Match.load(selectedRow.Cells[0].Value.ToString());
                selectedMatch = Match.load(selectedRow.Cells[0].Value.ToString());

                selectedMatch.Played = true;
                int i = 1;
                while (i <= 2)
                {
                    LineUp ln = i == 1 ? selectedMatch.LocalLineUp : selectedMatch.GuestLineUp;
                    //aggiorno il numero di cartellini
                    int j = 1;
                    List<Player> pl;
                    while (j <= 2)
                    {
                        pl = j == 1 ? ln.RegularPlayers : ln.ReservePlayers;
                        foreach (Player p in pl)
                        {
                            if (p.hasRed(selectedMatch.Id))
                                Player.load(p.Id).getRedCard();
                            if (p.hasYellow(selectedMatch.Id) && !p.hasRed(selectedMatch.Id))
                                Player.load(p.Id).getYellowCard();
                        }
                        j++;
                    }
                    pl = ln.notLineUp(0);
                    foreach (Player p in pl)
                        p.setCardsAndStatus();
                    i++;
                }
                pnlEvent.Enabled = false;
                dgEvents.Columns[5].Visible = false;

            }
        }

        private void txtMinute_KeyPress(object sender, KeyPressEventArgs e)
        {
            acceptOnlyNumber(e);
        }

        private void txtMinute_Leave(object sender, EventArgs e)
        {
            if (txtMinute.Text.Count() == 0 || txtMinute.Text == "0")
                txtMinute.Text = "1";
        }

        #endregion

        #region Dayweeks

        private void smiDayweeks_Click(object sender, EventArgs e)
        {
            if (smiDayweeks.Text == "Giornate")
            {
                showSlide(2);
                refreshTeamsCombos(0);
            }
            else
                showSlide(3);
        }
        
        private void dgDayweeks_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if (dgDayweeks.RowCount == 0 || e.RowIndex < 0)
                return;
            
            var row = dgDayweeks.Rows[e.RowIndex];

            switch (e.ColumnIndex)
            {
                case 3:
                {
                    Dayweek selectedDW = Dayweek.load(row.Cells[0].Value.ToString());
                    dtpDate.Value = selectedDW.Date;

                    btnAddDayweek.Image = OurLeague.Properties.Resources.save;
                    btnAddDayweek.Left = 164;
                    btnAD.Visible = true;
                    gbAddEditDayweek.Text = "Modifica giornata";
                    dgDayweeks.Enabled = false;
                    pnlDayweekDetails.Enabled = false;
                    gbAddEditDayweek.Visible = true;
                    lblFullCalendar.Visible = false;

                    break;
                }

                case 4:
                {
                    if (MessageBox.Show("Sei sicuro di voler proseguire con l'operazione?", "Cancellazione giornata", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                    {
                        Dayweek.load(row.Cells[0].Value.ToString()).delete();
                        refreshDayweeksGrid();
                    }

                    break;
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender">
        /// 0: inizializzazione combo;
        /// 1: cambio selezione combo LocalTeam
        /// 2: cambio selezione combo GuestTeam
        /// </param>
        private void refreshTeamsCombos(int sender)
        {
            if (dgDayweeks.SelectedRows.Count == 0)
                return;

            if (sender == 2 && cmbLocalTeam.Enabled == false)
                return;

            if (sender == 1 && cmbGuestTeam.Enabled == false)
                return;

            List<Match> matchesDayweek = Match.loadAll(dgDayweeks.SelectedRows[0].Cells[0].Value.ToString());
            if (matchesDayweek.Count == Team.Teams.Count / 2)
                return;

            List<Team> teams = Team.Teams.FindAll(t => !matchesDayweek.Exists(m => m.GuestLineUp.TeamId == t.Id) && !matchesDayweek.Exists(m => m.LocalLineUp.TeamId == t.Id));
            
            object oldSelection = null;
            if (sender == 0 || sender == 1)
            {
                cmbGuestTeam.Enabled = false;
                if (sender != 0)
                    oldSelection = cmbGuestTeam.SelectedValue;
                cmbGuestTeam.DataSource = teams.FindAll(t => (oldSelection != null && cmbLocalTeam.SelectedValue != null ? cmbLocalTeam.SelectedValue.ToString() != t.Id : true));
                if (oldSelection != null)
                    cmbGuestTeam.SelectedValue = oldSelection.ToString();

                cmbGuestTeam.Enabled = true;
            }

            oldSelection = null;
            if (sender == 0 || sender == 2)
            {
                cmbLocalTeam.Enabled = false;
                if (sender != 0)
                    oldSelection = cmbLocalTeam.SelectedValue;
                cmbLocalTeam.DataSource = teams.FindAll(t => (cmbGuestTeam.SelectedValue != null ? cmbGuestTeam.SelectedValue.ToString() != t.Id : true));
                if (oldSelection != null)
                    cmbLocalTeam.SelectedValue = oldSelection.ToString();

                cmbLocalTeam.Enabled = true;
            }
        }

        private void refreshMatchesGrid(String dayWeekId)
        {
            var queryMatchList = Match.loadAll(dayWeekId);

            foreach (Match m in queryMatchList)
                Event.loadAll(m);

            dgDayweekDetails.DataSource = queryMatchList.ToList();
            
            if (queryMatchList.Count == 0)
                pnlMatches.Visible = false;
            else
            {
                lblDayweekDetails.Text = "Dettagli " + Dayweek.load(dayWeekId).DayweekNumber + "^ giornata";
                pnlMatches.Visible = true;
            }
            lblDayweekEmpty.Visible = !pnlMatches.Visible;

            refreshTeamsCombos(0);
            gbAddNewMatch.Visible = !(queryMatchList.Count == Team.Teams.Count / 2);
            lblFullDayweek.Visible = !gbAddNewMatch.Visible;
            pnlDayweekDetails.Enabled = true;
            pnlDayweekDetails.Visible = true;
            lblDayWeekNotSelected.Visible = false;
            lblTotMatches.Text = "Tot. " + queryMatchList.Count;
        }

        private void refreshDayweeksGrid()
        {            
            dgDayweeks.DataSource = Dayweek.Dayweeks.ToList();
            lblTotDayweeks.Text = "Tot. " + Dayweek.Dayweeks.Count();
            setVisibleDayweekEditor();
            dgDayweeks_SelectionChanged(null, null);
        }

        private void dgDayweekDetails_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if (dgDayweekDetails.RowCount == 0 || e.RowIndex < 0) return;

            DataGridViewRow selectedRow = dgDayweekDetails.SelectedRows[0];
            Match selectedMatch = Match.load(selectedRow.Cells[0].Value.ToString());

            switch (e.ColumnIndex)
            {
                case 3:
                {
                    Team[] lineUp = new Team[] { Team.load(selectedMatch.LocalLineUp.TeamId), Team.load(selectedMatch.GuestLineUp.TeamId) };
                    cmbChooseTeamLU.DisplayMember = "Name";
                    cmbChooseTeamLU.ValueMember = "Id";
                    cmbChooseTeamLU.DataSource = lineUp;
                    lblDayweekN.Text = selectedMatch.Dayweek.DayweekNumber + "^ giornata";
                    lblMatchTitle.Text = selectedMatch.LocalLineUp.TeamName + " vs. " + selectedMatch.GuestLineUp.TeamName;
                    matchStatus(selectedMatch);
                    tcLineUpEvents.SelectedIndex = 0;
                    pctLocalTeam.Image = Util.loadImageFromResources(selectedMatch.LocalLineUp.TeamName.ToLower() + "_small");
                    pctGuestTeam.Image = Util.loadImageFromResources(selectedMatch.GuestLineUp.TeamName.ToLower() + "_small");
                    smiDayweeks.Text = "Giornate > Formazioni e Eventi";
                    smiDayweeks_Click(null, null);
                    cmbChooseTeamLU_SelectedIndexChanged(null, null);
                    break;
                }

                case 4:
                {
                    if (MessageBox.Show("Sei sicuro di voler proseguire con l'operazione?", "Cancellazione partita", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                    {
                        selectedMatch.delete();
                        refreshMatchesGrid(selectedMatch.Dayweek.Id);
                    }

                    break;
                }
            }
        }

        private void btnAddDayweek_Click(object sender, EventArgs e)
        {
            Dayweek selectedDW;
            if (gbAddEditDayweek.Text == "Modifica giornata")
                selectedDW = Dayweek.load(dgDayweeks.SelectedRows[0].Cells[0].Value.ToString());
            else
                selectedDW = new Dayweek();

            if (Dayweek.Dayweeks.Exists(dw => dw.Date.Date.CompareTo(dtpDate.Value.Date) == 0 && dw != selectedDW))
            {
                MessageBox.Show("Impossibile continuare, esiste già una giornata con la data specificata.", "Errore nuova giornata", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            selectedDW.Date = dtpDate.Value.Date;
            selectedDW.save();
            refreshDayweeksGrid();
            btnAD_Click(null, null);
            dtpDate.Value = dtpDate.Value.AddDays(7);
        }

        private void btnAddMatch_Click(object sender, EventArgs e)
        { 
            if (Match.Matches.Exists(m => m.LocalLineUp.TeamId == cmbLocalTeam.SelectedValue.ToString() && m.GuestLineUp.TeamId == cmbGuestTeam.SelectedValue.ToString()))
            {
                MessageBox.Show("La partita specificata è già in calendario.", "Errore inserimento partita", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }
            
            Match nm = new Match();
            nm.Dayweek = Dayweek.load(dgDayweeks.SelectedRows[0].Cells[0].Value.ToString());
            nm.Referee = Match.getRandomReferee(dgDayweeks.SelectedRows[0].Cells[0].Value.ToString());
            nm.LocalLineUp = new LineUp(Team.load(cmbLocalTeam.SelectedValue.ToString()));
            nm.GuestLineUp = new LineUp(Team.load(cmbGuestTeam.SelectedValue.ToString()));
            nm.save();

            refreshMatchesGrid(dgDayweeks.SelectedRows[0].Cells[0].Value.ToString());
        }

        private void setVisibleDayweekEditor()
        {
            gbAddEditDayweek.Visible = !( Dayweek.Dayweeks.Count() == 2 * (Team.Teams.Count() % 2 == 0 ? Team.Teams.Count() - 1 : Team.Teams.Count()) );
            lblFullCalendar.Visible = !gbAddEditDayweek.Visible;
        }

        private void btnAD_Click(object sender, EventArgs e)
        {
            btnAddDayweek.Image = OurLeague.Properties.Resources.add;
            btnAddDayweek.Left = 186;
            btnAD.Visible = false;
            gbAddEditDayweek.Text = "Aggiungi giornata";
            dgDayweeks.Enabled = true;
            pnlDayweekDetails.Enabled = true;
            setVisibleDayweekEditor();
        }

        private void dgDayweeks_SelectionChanged(object sender, EventArgs e)
        {
            if (dgDayweeks.SelectedRows.Count == 0)
            {
                pnlDayweekDetails.Visible = false;
                lblDayWeekNotSelected.Visible = true;
                return;
            }

            refreshMatchesGrid(dgDayweeks.SelectedRows[0].Cells[0].Value.ToString());
        }

        private void cmbLocalTeam_SelectedIndexChanged(object sender, EventArgs e)
        {
            refreshTeamsCombos(1);
        }

        private void cmbGuestTeam_SelectedIndexChanged(object sender, EventArgs e)
        {
            refreshTeamsCombos(2);
        }

        private void dgLineUp_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if (dgLineUp.RowCount == 0 || e.RowIndex < 0) return;
            DataGridViewRow selectedRow = dgDayweekDetails.SelectedRows[0];
            Match selectedMatch = Match.load(selectedRow.Cells[0].Value.ToString());


            switch (e.ColumnIndex)
            {
                case 7:
                case 8:
                    {
                        if (!(selectedMatch.Played) && !(Event.Events.Exists(E => E.MatchId == selectedMatch.Id)))
                            dgLineUp.SelectedRows[0].Cells[e.ColumnIndex == 8 ? 7 : 8].Value = 0;
                        break;
                    }
            }
        }

        private void dgLineUp_CurrentCellDirtyStateChanged(object sender, EventArgs e)
        {
            if (dgLineUp.IsCurrentCellDirty)
                dgLineUp.CommitEdit(DataGridViewDataErrorContexts.Commit);
        }

        private void dgLineUp_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            updateLineUpCount();
        }

        #endregion
    }
}
